<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>optim</title>
  </head>
  <body bgcolor="#FFFFFF">
    <center>Scilab Function</center>
    <div align="right">Last update : 17/05/2005</div>
    <p>
      <b>optim</b> -  non-linear optimization routine</p>
    <h3>
      <font color="blue">Calling Sequence</font>
    </h3>
    <dl>
      <dd>
        <tt>[f,xopt]=optim(costf,x0)  </tt>
      </dd>
      <dd>
        <tt>[f [,xopt [,gradopt [,work]]]]=optim(costf [,&lt;contr&gt;],x0
      [,algo] [,df0 [,mem]] [,work] [,&lt;stop&gt;] [,&lt;params&gt;] [,imp=iflag])  </tt>
      </dd>
    </dl>
    <h3>
      <font color="blue">Parameters</font>
    </h3>
    <ul>
      <li>
        <tt>
          <b>costf</b>
        </tt>: external, i.e Scilab function list or string
	    (<tt>
          <b>costf</b>
        </tt> is the cost function: see below its calling
	    sequence (Scilab or Fortran)). See also external for details about
	    external functions.</li>
      <li>
        <tt>
          <b>x0</b>
        </tt>: real vector (initial value of variable to be minimized).</li>
      <li>
        <tt>
          <b>f</b>
        </tt>: value of optimal cost (<tt>
          <b>f=costf(xopt)</b>
        </tt>)</li>
      <li>
        <tt>
          <b>xopt</b>
        </tt>: best value of <tt>
          <b>x</b>
        </tt> found.</li>
      <li>
        <tt>
          <b>&lt;contr&gt;</b>
        </tt>: keyword representing the following sequence of arguments:
	    <tt>
          <b>'b',binf,bsup</b>
        </tt>  with <tt>
          <b>binf</b>
        </tt> and 
	    <tt>
          <b>bsup</b>
        </tt> are real vectors with same dimension as
	    <tt>
          <b>x0</b>
        </tt>. <tt>
          <b>binf</b>
        </tt> and <tt>
          <b>bsup</b>
        </tt> are lower
	    and upper bounds on <tt>
          <b>x</b>
        </tt>.</li>
      <li>
        <tt>
          <b>algo</b>
        </tt>: Character string used to sprecify the algorithm to use. The
	    possible values are <tt>
          <b>'qn'</b>
        </tt> for quasi-Newton (default) or
	    <tt>
          <b>'gc'</b>
        </tt> for conjugate gradient or <tt>
          <b>'nd'</b>
        </tt> for
	    non-differentiable.  Note that
	    <tt>
          <b>'nd'</b>
        </tt> does not accept bounds on <tt>
          <b>x</b>
        </tt>.</li>
      <li>
        <tt>
          <b>df0</b>
        </tt>: real scalar. Guessed decreasing of <tt>
          <b>f</b>
        </tt> at first
	    iteration. (<tt>
          <b>df0=1</b>
        </tt> is the default value).</li>
      <li>
        <tt>
          <b>mem :  </b>
        </tt>integer, number of variables used to approximate the  Hessian,
	    (<tt>
          <b>algo='gc' or 'nd'</b>
        </tt>). Default value is around 6.</li>
      <li>
        <tt>
          <b>&lt;stop&gt;</b>
        </tt>:  keyword representing the sequence of optional parameters
	    controlling the  convergence of the algorithm. 
            <tt>
          <b>'ar',nap [,iter [,epsg [,epsf [,epsx]]]]</b>
        </tt>
        <ul>
          <li>
            <tt>
              <b>"ar"  </b>
            </tt>: reserved keyword for stopping rule selection defined as
		  follows:</li>
          <li>
            <tt>
              <b>nap</b>
            </tt>: maximum number of calls to <tt>
              <b>costf</b>
            </tt> allowed
		  (default is 100).</li>
          <li>
            <tt>
              <b>iter</b>
            </tt>: maximum number of iterations allowed (default is 100).</li>
          <li>
            <tt>
              <b>epsg</b>
            </tt>: threshold on gradient norm.</li>
          <li>
            <tt>
              <b>epsf</b>
            </tt>: threshold controlling decreasing of <tt>
              <b>f</b>
            </tt>
          </li>
          <li>
            <tt>
              <b>epsx</b>
            </tt>: threshold controlling variation of <tt>
              <b>x</b>
            </tt>. This
		  vector (possibly matrix) of same size as <tt>
              <b>x0</b>
            </tt> can
		  be used to scale <tt>
              <b>x</b>
            </tt>.</li>
        </ul>
      </li>
      <li>
        <tt>
          <b>&lt;params&gt; </b>
        </tt>: keyword representing the sequence of arguments: 
          <tt>
          <b>'ti', valti ,'td', valtd</b>
        </tt> which can be used to pass argument to
	    an external written in C or Fortran (see below).</li>
      <li>
        <tt>
          <b>"imp=iflag"  </b>
        </tt>: named argument used to set the trace mode. <tt>
          <b>iflag=0</b>
        </tt>
	    nothing (execpt errors) is reported, <tt>
          <b>iflag=1</b>
        </tt> initial
	    and final reports, <tt>
          <b>iflag=2</b>
        </tt> adds a report per
	    iteration, <tt>
          <b>iflag&gt;2</b>
        </tt> add reports on linear
	    search. Warning, most of these reports are written on the Scilab
	    standard output.</li>
      <li>
        <tt>
          <b>gradopt</b>
        </tt>:  gradient of <tt>
          <b>costf</b>
        </tt> at <tt>
          <b>xopt</b>
        </tt>
      </li>
      <li>
        <tt>
          <b>work</b>
        </tt>: working array for hot restart for quasi-Newton method. This
	    array is automatically initialized by <tt>
          <b>optim</b>
        </tt> when
	    <tt>
          <b>optim</b>
        </tt> is invoked. It can be used as input parameter to
	    speed-up the calculations.</li>
    </ul>
    <h3>
      <font color="blue">Description</font>
    </h3>
      Non-linear optimization routine for programs without constraints or with
      bound constraints:<pre>
      
      min costf(x) w.r.t x.
      
    </pre>
    <p>
      <tt>
        <b>costf</b>
      </tt> is an "external" i.e a Scilab function, a
      list or a string giving the name of a C or Fortran routine (see
      "external").
      
      This external must return the value <tt>
        <b>f</b>
      </tt> of the cost function
      at the point <tt>
        <b>x</b>
      </tt> and the gradient <tt>
        <b>g</b>
      </tt> of the cost
      function at the point <tt>
        <b>x</b>
      </tt>. 
    </p>
    <dl>
      <dd>
        <b>- Scilab function case</b>
        <p>If <tt>
            <b>costf</b>
          </tt> is a Scilab function, the calling sequence
	  for <tt>
            <b>costf</b>
          </tt> must be:
	  <tt>
            <b>[f,g,ind]=costf(x,ind)</b>
          </tt>
        </p>Here, <tt>
          <b>costf</b>
        </tt> is a function which returns <tt>
          <b>f</b>
        </tt>,
	  value (real number) of cost function at <tt>
          <b>x</b>
        </tt>, and
	  <tt>
          <b>g</b>
        </tt>, gradient vector of cost function at
	  <tt>
          <b>x</b>
        </tt>. The variable <tt>
          <b>ind</b>
        </tt>  is described below.</dd>
      <dd>
        <b>- List case</b>
        <p>If <tt>
            <b>costf</b>
          </tt> is a list, it should be of the form:
	  <tt>
            <b>list(real_costf, arg1,...,argn)</b>
          </tt> with <tt>
            <b>real_costf</b>
          </tt>
	  a Scilab function with calling sequence :
	  <tt>
            <b>[f,g,ind]=costf(x,ind,arg1,... argn)</b>
          </tt>. The
	  <tt>
            <b>x</b>
          </tt>, <tt>
            <b>f</b>
          </tt>, <tt>
            <b>g</b>
          </tt>, <tt>
            <b>ind</b>
          </tt>
	  arguments have the same meaning that above. <tt>
            <b>argi</b>
          </tt>
	  arguments can be used to pass function parameters.</p>
      </dd>
      <dd>
        <b>- String case</b>
        <p>If <tt>
            <b>costf</b>
          </tt> is a character string, it refers to the name
	  of a C or Fortran routine which must be linked to Scilab </p>
        <dl>
          <dd>
            <b>* Fortran case</b>
            <p>The generic calling sequence for the Fortran subroutine is: 
	      <tt>
                <b>subroutine costf(ind,n,x,f,g,ti,tr,td)</b>
              </tt> with the
	      following declarations:</p>
            <pre>
	      
	      integer ind,n ti(*)
	      double precision x(n),f,g(n),td(*)
	      real tr(*)
	      
	    </pre>The argument <tt>
              <b>ind</b>
            </tt> is described below.<p>The Fortran subroutine <tt>
                <b>costf</b>
              </tt> must return <tt>
                <b>f</b>
              </tt>
	      and the vector <tt>
                <b>g</b>
              </tt>, given <tt>
                <b>x, ind, n, ti, tr,td</b>
              </tt>.</p>
            <p>
              <tt>
                <b>ti,tr,td</b>
              </tt> can be used to initialize parameters. In
	      the calling sequence of <tt>
                <b>optim</b>
              </tt>, the keyword
	      <tt>
                <b>&lt;params&gt;'</b>
              </tt> can be replaced by <tt>
                <b>'ti', valti ,'td', valtd</b>
              </tt>
		.  Then, the routine  <tt>
                <b>costf</b>
              </tt> is
	      evaluated with <tt>
                <b>ti=valti</b>
              </tt> and 
	      <tt>
                <b>td=valtd</b>
              </tt> whatever the value of
	      <tt>
                <b>ind</b>
              </tt>. Thus, the Scilab variables <tt>
                <b>valti</b>
              </tt>
	      and <tt>
                <b>valtd</b>
              </tt> (integer vector and real vector) are sent
	      to the routine <tt>
                <b>costf</b>
              </tt>.</p>
          </dd>
          <dd>
            <b>* C case</b>
            <p>The generic calling sequence for the C procedure is: 
	    <tt>
                <b>void costf(int *ind, int *n, double *x, double *f, double *g, int *ti, float *tr, double *td)</b>
              </tt>
             with the following declarations:</p>
            <p>The argument <tt>
                <b>ind</b>
              </tt> is described below.</p>
            <p>The C procedure <tt>
                <b>costf</b>
              </tt> must return <tt>
                <b>f</b>
              </tt>
	      and the vector <tt>
                <b>g</b>
              </tt>, given <tt>
                <b>x, ind, n, ti, tr, td</b>
              </tt>.</p>
            <p>
              <tt>
                <b>ti,tr,td</b>
              </tt> can be used to initialize parameters. In
	      the calling sequence of <tt>
                <b>optim</b>
              </tt>, the string
	      <tt>
                <b>'in'</b>
              </tt> can be replaced by <tt>
                <b>'ti', valti ,'td', valtd</b>
              </tt>.  
	      Then, the procedure  <tt>
                <b>costf</b>
              </tt> is
	      evaluated with <tt>
                <b>ti=valti</b>
              </tt> and 
	      <tt>
                <b>td=valtd</b>
              </tt> whatever the value of
	      <tt>
                <b>ind</b>
              </tt>. Thus, the Scilab variables <tt>
                <b>valti</b>
              </tt>
	      and <tt>
                <b>valtd</b>
              </tt> (integer vector and real vector) are sent
	      to the procedure <tt>
                <b>costf</b>
              </tt>.</p>
          </dd>
        </dl>
      </dd>
    </dl>
    <p>If <tt>
        <b>ind=2</b>
      </tt> (resp. <tt>
        <b>3, 4</b>
      </tt>), <tt>
        <b>costf</b>
      </tt>
      must provide <tt>
        <b>f</b>
      </tt> (resp. <tt>
        <b>g, f</b>
      </tt> and
      <tt>
        <b>g</b>
      </tt>).</p>
    <p>If <tt>
        <b>ind=1</b>
      </tt> nothing is computed (used for display purposes
      only).</p>
    <p> On output, <tt>
        <b>ind&lt;0</b>
      </tt>  means that <tt>
        <b>f</b>
      </tt> cannot
      be evaluated at <tt>
        <b>x</b>
      </tt> and <tt>
        <b>ind=0</b>
      </tt> interrupts
      the optimization.</p>
    <h3>
      <font color="blue">Examples</font>
    </h3>
    <pre>
    
    // External function written in Scilab
    xref=[1;2;3];x0=[1;-1;1]
    deff('[f,g,ind]=cost(x,ind)','f=0.5*norm(x-xref)^2,g=x-xref');
    [f,xopt]=optim(cost,x0)      //Simplest call
    [f,xopt,gopt]=optim(cost,x0,'gc')  // By conjugate gradient
    [f,xopt,gopt]=optim(cost,x0,'nd')  //Seen as non differentiable
    [f,xopt,gopt]=optim(cost,'b',[-1;0;2],[0.5;1;4],x0) //  Bounds on x
    [f,xopt,gopt]=optim(cost,'b',[-1;0;2],[0.5;1;4],x0,'gc') //  Bounds on x
    [f,xopt,gopt]=optim(cost,'b',[-1;0;2],[0.5;1;4],x0,'gc','ar',3)

    // External function written in C (C compiler required)
    // write down the C code (Rosenbrock problem)
    C=['#include &lt;math.h&gt;'
    'double sq(double x)'
    '{ return x*x;}'
    'void rosenc(int *ind, int *n, double *x, double *f, double *g, '
    '                                int *ti, float *tr, double *td)'
    '{'
    '  double p;'
    '  int i;'
    '  p=td[0];'
    '  if (*ind==2||*ind==4) {'
    '    *f=1.0;'
    '    for (i=1;i&lt;*n;i++)'
    '      *f+=p*sq(x[i]-sq(x[i-1]))+sq(1.0-x[i]);'
    '  }'
    '  if (*ind==3||*ind==4) {'
    '    g[0]=-4.0*p*(x[1]-sq(x[0]))*x[0];'
    '    for (i=1;i&lt;*n-1;i++)'
    '      g[i]=2.0*p*(x[i]-sq(x[i-1]))-4.0*p*(x[i+1]-sq(x[i]))*x[i]-2.0*(1.0-x[i]);'
    '    g[*n-1]=2.0*p*(x[*n-1]-sq(x[*n-2]))-2.0*(1.0-x[*n-1]);'
    '  }'
    '}'];
    mputl(C,TMPDIR+'/rosenc.c')
    // compile the C code
    l=ilib_for_link('rosenc','rosenc.o',[],'c',TMPDIR+'/Makefile');
    // incremental linking
    link(l,'rosenc','c')
    //solve the problem
    x0=[40;10;50];
    p=100;
    [f,xo,go]=optim('rosenc',x0,'td',p)

    // External function written in Fortran (Fortran compiler required)
    // write down the Fortran  code (Rosenbrock problem)
 F=[ '      subroutine rosenf(ind, n, x, f, g, ti, tr, td)'
     '      integer ind,n,ti(*)'
     '      double precision x(n),f,g(n),td(*)'
     '      real tr(*)'
     'c'
     '      double precision y,p'
     '      p=td(1)'
     '      if (ind.eq.2.or.ind.eq.4) then'
     '        f=1.0d0'
     '        do i=2,n'
     '          f=f+p*(x(i)-x(i-1)**2)**2+(1.0d0-x(i))**2'
     '        enddo'
     '      endif'
     '      if (ind.eq.3.or.ind.eq.4) then'
     '        g(1)=-4.0d0*p*(x(2)-x(1)**2)*x(1)'
     '        if(n.gt.2) then'
     '          do i=2,n-1'
     '            g(i)=2.0d0*p*(x(i)-x(i-1)**2)-4.0d0*p*(x(i+1)-x(i)**2)*x(i)'
     '     &amp;           -2.0d0*(1.0d0-x(i))'
     '          enddo'
     '        endif'
     '        g(n)=2.0d0*p*(x(n)-x(n-1)**2)-2.0d0*(1.0d0-x(n))'
     '      endif'
     '      return'
     '      end'];

    mputl(F,TMPDIR+'/rosenf.f')
    // compile the Fortran code
    l=ilib_for_link('rosenf','rosenf.o',[],'f',TMPDIR+'/Makefile');
    // incremental linking
    link(l,'rosenf','f')
    //solve the problem
    x0=[40;10;50];
    p=100;
    [f,xo,go]=optim('rosenf',x0,'td',p)

 
    
  </pre>
    <h3>
      <font color="blue">See Also</font>
    </h3>
    <p>
      <a href="../programming/external.htm">
        <tt>
          <b>external</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="quapro.htm">
        <tt>
          <b>quapro</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="linpro.htm">
        <tt>
          <b>linpro</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="datafit.htm">
        <tt>
          <b>datafit</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="leastsq.htm">
        <tt>
          <b>leastsq</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="numdiff.htm">
        <tt>
          <b>numdiff</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="derivative.htm">
        <tt>
          <b>derivative</b>
        </tt>
      </a>,&nbsp;&nbsp;<a href="NDcost.htm">
        <tt>
          <b>NDcost</b>
        </tt>
      </a>,&nbsp;&nbsp;</p>
  </body>
</html>
